package learn;

public class learn {

    class inner {
        //内部类 可以直接访问外部的成员包括私有  外部类访问内部类的成员 必须创建对象

        //内部类分为 成员内部类 静态内部类 局部内部类 匿名内部类 前三种了解 匿名内部类掌握

//        成员内部类 属于外部类的成员 如car中的engine 相当于成员 可以被private protected static（静态内部类 不叫成员内部类了就）修饰
//          成员内部类里面jdk16之前不能定义静态变量 16才可以可以定义静态变量
        //获取内部类成员的方法  1. 外部类中编写方法 对外提供内部类对象
        //public Inner getInner(){ return new Inner(); }
        //Outer o=new Outer();   o.getInner();

        //                    2. 直接创建  外部类名.内部类名. 对象名=外部类对象.内部类对象
        //                    car.Engine ce=new car().new Engine();

        //如果Inner是private修饰的内部类 在外部类中编写方法进行调用

//        public class Outer(){
//            private int a=10;
//            class Inner{
//                private int a=20;
//                public void show(){
//                    int a=30;
//                    System.out.println(Outer.this.a);//10
//                    System.out.println(this.a);//20
//                    System.out.println(a);//30
//                }
//            }
//        }

        //当创建对象时堆区会有两个空间出现 一个是外部类对象 存放a=10 地址值假设是001
        //另外一个是内部类对象 存放int a=20 地址是002  会在这块空间里默认生成一个Outer.this 记录Outer的地址值001
        //Outer.Inner oi=new Outer().new Inner();
        //此时oi存放的地址是002

        //当调用show方法时 调用者为002 a先找方法里的a this.a从调用者里找a的值就是002里 Outer.this.a就是从外部类里找a




        //静态内部类 成员内部类被static修饰就是静态内部类 只能访问静态成员和静态方法 访问非静态只能创建外部类的对象
        //调用静态内部类的方法时 如果方法是静态的 直接 Outer.Inner.method();
        //方法是非静态的 就先创建静态内部类的对象 然后通过对象调用  Outer.Inner oi=new Outer.Inner();
        //                                                      oi.method();


        //作用不大
        //局部内部类 将内部类定义在方法里面就叫做局部内部类  可以被final 等修饰局部变量的词修饰 不能被修饰成员的词修饰 例如public private protected
        //无法直接使用局部内部类  需要创建局部内部类的对象 Inner i=new Inner();   i.method();   Inner.method2();
        //局部内部类可以直接访问外部类的成员 也可以访问方法里的局部变量



        //重要
        //匿名内部类
        //格式 new+接口名或者类名(){
        // 重写方法
        // };
        //匿名内部类的对象 new Student();
        //匿名内部类可以当作参数传给方法 如果只调用一次可以直接写一个匿名内部类然后放进方法的括号里

        //Swim s=new Swim(){
        // System.out.println("有用");
        // };
        //整体可以理解为接口的实现类对象  相当于接口多态

        //new Swim(){
        // System.out.println("有用");
        // }.swim();
        //可以理解为一个对象调用方法
    }
}
